#ifndef _AT_CHAT_H_
#define _AT_CHAT_H_

#include <stdio.h>
#include <stdbool.h>

#include "task.h"


#define MAX_AT_CMD_LEN      128

#define AT_DEBUG(...)       printf("[AT]:");printf(__VA_ARGS__)
#define AT_GET_TICKET()     xTaskGetTickCount()

struct at_obj;

/* urc处理项 */
typedef struct {
    const char *prefix;      /* 需要匹配的头部 */
    void (*handler)(char *recvbuf, int size);
}utc_item_t;

/* AT接口适配器 */
typedef struct {
    unsigned int (*write)(const void *buf, unsigned int len);   /* 发送接口 */
    unsigned int (*read)(void *buf, unsigned int len);          /* 接收接口 */
    void         (*error)(void);                                /* AT执行异常事件 */
    utc_item_t    *utc_tbl;                                     /* urc表 */
    unsigned char *urc_buf;                                     /* urc接收缓存区 */
    unsigned char *recv_buf;                                    /* 数据缓冲区 */
    unsigned short urc_tbl_count;                               /* urc表项个数 */
    unsigned short urc_bufsize;                                 /* urc缓冲区大小 */
    unsigned short recv_bufsize;                                /* 接收缓冲区大小 */
}at_adapter_t;

/* AT作业运行环境 */
typedef struct {
    int i,j,state;
    void *params;
    void (*reset_timer)(struct at_obj *at);
    bool (*is_timeout)(struct at_obj *at, unsigned int ms);
    void (*printf)(struct at_obj *at, const char * fmt, ...);
    char *(*find)(struct at_obj *at, const char *expect);
    char *(*recvbuf)(struct at_obj *at);
    unsigned int (*recvlen)(struct at_obj *at);
    void (*recvclr)(struct at_obj *at);
    bool (*abort)(struct at_obj *at);
}at_env_t;


typedef enum {
    AT_RET_OK = 0,
    AT_RET_ERROR,
    AT_RET_TIMEOUT,
    AT_RET_ABORT,
}at_return;

typedef struct{
    void *param;
    char *recvbuf;
    unsigned short recvcnt;
    at_return ret;
}at_response_t;

typedef void (*at_callback_t)(at_response_t *r);

typedef struct {
    unsigned int state : 3;
    unsigned int type : 3;
    unsigned int abort : 1;
    void *param;
    void *info;
    struct list_head node;
}at_item_t;

typedef struct at_obj{
    at_adapter_t        adap;               /* AT适配接口 */
    at_env_t            env;                /* 作业运行环境 */
    at_item_t           item[10];           /* 最大容纳10个作业 */
    at_item_t           *cursor;            /* 当前作业项 */
    struct list_head    ls_ready, ls_idle;  /* 就绪，空闲作业链 */
    unsigned int        timer;
    unsigned int        urc_timer;
    at_return           ret;
    unsigned short      urc_cnt,recv_cnt;
    unsigned char       suspend:1;
}at_obj_t;

typedef struct {
    void (*sender)(at_env_t *e);                            /*自定义发送器 */
    const char *matcher;                                    /*接收匹配串 */
    at_callbatk_t  cb;                                      /*响应处理 */
    unsigned char  retry;                                   /*错误重试次数 */
    unsigned short timeout;                                 /*最大超时时间 */
}at_cmd_t;

void at_obj_init(at_obj_t *at, const at_adapter_t *);

bool at_send_singlline(at_obj_t *at, at_callbatk_t cb, const char *singlline);

bool at_send_multiline(at_obj_t *at, at_callbatk_t cb, const char **multiline);

bool at_do_cmd(at_obj_t *at, void *params, const at_cmd_t *cmd);

bool at_do_work(at_obj_t *at, int (*work)(at_env_t *e), void *params);

void at_item_abort(at_item_t *it);                          /*终止当前作业*/
         
bool at_obj_busy(at_obj_t *at);                              /*忙判断*/

void at_suspend(at_obj_t *at);

void at_resume(at_obj_t *at);

void at_poll_task(at_obj_t *at);



#endif // !_AT_CHAT_H_



